﻿using System;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;
using Asistente.Model.Representation;
using System.Reflection;
using Asistente.Managers;
using Asistente.Model.General;


namespace Asistente.Serialization
{    
    public class Serializer
    {
        private static Serializer instance = new Serializer();

        public static Serializer Instance
        {
            get
            {
                if (instance == null)
                    instance = new Serializer();
                return instance;
            }
        }

        private static List<Type> GetDerivedTypesList()
        {
            Type baseType = typeof(IElement);
            List<Type> derivedTypesList = new List<Type>();
            foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (type != baseType && baseType.IsAssignableFrom(type))
                {
                    derivedTypesList.Add(type);
                }
            }
            return derivedTypesList;
        }

        //Serializacion de la aplicacion, creando un archivo xml en path
        public void Serialize(Application app, string path)
        {
            try
            {
                XmlSerializer x = new XmlSerializer(typeof(Application), GetDerivedTypesList().ToArray());
                using (FileStream fs = new FileStream(path, FileMode.Create))
                {
                    x.Serialize(fs, app);
                }
            }
            catch (Exception)
            {
                ThrowError("An Error ocurred during Serialization.\n The measurment data will not be saved.", "Export Error"); 
             }
        }

        //Creacion de un archivo html en path segun text
        public void SaveHTML(string text, string path)
        {
            try
            {
                StreamWriter sw = new StreamWriter(path);
                sw.Write(text);
                sw.Close();
            }
            catch (Exception)
            {
                ThrowError("An Error ocurred during saving.", "Saving Error");

            }
        }

        //Deserializacion de la aplicacion, segun el xml ubicado en path
        public Application Deserialize(string path)
        {
            try
            {
                XmlSerializer x = new XmlSerializer(typeof(Application), GetDerivedTypesList().ToArray());
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                    return x.Deserialize(fs) as Application; //Cast                
                }
            }
            catch(Exception)
            {
                ThrowError("An error ocurred during Deserialization.\nThe measurement data will not be loaded.", "Import Error");
                return null;
            }
        }

        //Dialogo para obtener guardar en una ruta un xml
        public string SaveFileDialog() 
        {
            var dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = Numerator.Instance.GetName("File");
            dlg.DefaultExt = ".xml"; 
            dlg.Filter = "Text documents (.xml)|*.xml"; 

            // Show save file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process save file dialog box results
            if (result == true)
            {
                // Save document
                return dlg.FileName;
            }
            return null;
        }

        //Dialogo para obtener guardar en una ruta un html
        public string SaveHtmlDialog()
        {
            var dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = Numerator.Instance.GetName("File");
            dlg.DefaultExt = ".html";
            dlg.Filter = "All files (*.*)|*.*";

            // Show save file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process save file dialog box results
            if (result == true)
            {
                // Save document
                return dlg.FileName;
            }
            return null;
        }

        //Dialogo para obtener un archivo de una ruta
        public string OpenFileDialog() 
        {
            var dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.FileName = Numerator.Instance.GetName("File");
            dlg.DefaultExt = ".xml"; 
            dlg.Filter = "Text documents (.xml)|*.xml"; 

            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results
            if (result == true)
            {
                // Open document
                return dlg.FileName;
            }
            return null;
        }
        
        public void ThrowError(String errorDescription, String title)
        {
            System.Windows.MessageBox.Show(errorDescription, title);
        }
    }
}